﻿#include "EditorWindowGroupViewModel.h"
#include "Framework/Editor.h"
#include "Window/EditorWindowGroupModel.h"
#include "Window/EditorMainWindowModel.h"
#include "Window/EditorMainWindowViewModel.h"
#include "Window/EditorToolTipWindowViewModel.h"
#include "Window/EditorContextMenuViewModel.h"

#include "Framework/Application.h"

#include "Pages/EditorPageViewModel.h"


static REditorWindowGroupViewModel*
    GEditorWindowGroupViewModel = nullptr;

void REditorWindowGroupViewModel::Initialize()
{
    GEditorWindowGroupViewModel = this;

    {
        //注册剪切快捷键
        SShortcutKey CutKey;
        CutKey.Key = EKey::X;
        CutKey.bAnyCtrlDown=true;

        TScriptDelegate <bool()> OnCut;
        OnCut.Bind(this, &REditorWindowGroupViewModel::CutInActivedPage);

        RApplication::GetApplication()
            ->RegisterShorcut(CutKey,OnCut);

        //注册复制快捷键
        SShortcutKey CopyKey;
        CopyKey.Key = EKey::C;
        CopyKey.bAnyCtrlDown=true;

        TScriptDelegate <bool()> OnCopy;
        OnCopy.Bind(this, &REditorWindowGroupViewModel::CopyInActivedPage);

        RApplication::GetApplication()
            ->RegisterShorcut(CopyKey,OnCopy);

        //注册粘贴快捷键
        SShortcutKey PasteKey;
        PasteKey.Key = EKey::V;
        PasteKey.bAnyCtrlDown=true;

        TScriptDelegate <bool()> OnPaste;
        OnPaste.Bind(this, &REditorWindowGroupViewModel::PasteInActivedPage);

        RApplication::GetApplication()
            ->RegisterShorcut(PasteKey,OnPaste);

        
        //注册搜索快捷键
        SShortcutKey SearchKey;
        SearchKey.Key = EKey::F;
        SearchKey.bAnyCtrlDown=true;

        TScriptDelegate <bool()> OnSearch;
        OnSearch.Bind(this, &REditorWindowGroupViewModel::OpenFindTextDialogInActivedPage);

        RApplication::GetApplication()
            ->RegisterShorcut(SearchKey,OnSearch);

        //注册替换
        SShortcutKey ReplaceKey;
        ReplaceKey.Key = EKey::H;
        ReplaceKey.bAnyCtrlDown=true;

        TScriptDelegate <bool()> OnReplace;
        OnReplace.Bind(this, &REditorWindowGroupViewModel::OpenReplaceTextDialogInActivedPage);

        RApplication::GetApplication()
            ->RegisterShorcut(ReplaceKey,OnReplace);

        //注册保存
        SShortcutKey SaveKey;
        SaveKey.Key = EKey::S;
        SaveKey.bAnyCtrlDown=true;

        TScriptDelegate <bool()> OnSave;
        OnSave.Bind(this, &REditorWindowGroupViewModel::SaveActivedPage);

        RApplication::GetApplication()
            ->RegisterShorcut(SaveKey,OnSave);

        //注册撤销
        SShortcutKey UndoKey;
        UndoKey.Key = EKey::Z;
        UndoKey.bAnyCtrlDown=true;

        TScriptDelegate <bool()> OnUndo;
        OnUndo.Bind(this, &REditorWindowGroupViewModel::UndoActivedPage);

        RApplication::GetApplication()
            ->RegisterShorcut(UndoKey,OnUndo);

        //注册重做
        SShortcutKey RedoKey;
        RedoKey.Key = EKey::Y;
        RedoKey.bAnyCtrlDown=true;

        TScriptDelegate <bool()> OnRedo;
        OnRedo.Bind(this, &REditorWindowGroupViewModel::RedoActivedPage);

        RApplication::GetApplication()
            ->RegisterShorcut(RedoKey,OnRedo);

    }


    for(auto& RegisteredWindow: REditorWindowGroupModel::Get()->GetWindows())
    {
        auto ViewModel = CreateWindowViewModel(RegisteredWindow);
        RegisterWindow(ViewModel);
    }

    //bind delegates
    REditorWindowGroupModel::Get()->OnWindowRegistered.Add([this](TSharedObjectPtr<REditorWindowModel> Window)
    {
        auto ViewModel = CreateWindowViewModel(Window);
        RegisterWindow(ViewModel);
    });

    REditorWindowGroupModel::Get()->OnWindowUnregistered.Add([this](TSharedObjectPtr<REditorWindowModel> Window)
    {
        auto ViewModels = Windows;
        for(auto ViewModel: ViewModels)
        {
            if(ViewModel->GetModel() == Window)
            {
                UnregisterWindow(ViewModel);
                break;
            }
        }
    });

    Tooltip=NewObject<REditorToolTipWindowViewModel>(this);

    ContextMenu=NewObject<REditorContextMenuViewModel>(this);
}

void REditorWindowGroupViewModel::Deinitialize()
{
    GEditorWindowGroupViewModel = nullptr;
}

REditorWindowGroupViewModel *REditorWindowGroupViewModel::Get()
{
    return GEditorWindowGroupViewModel;
}





void REditorWindowGroupViewModel::RegisterWindow(TSharedObjectPtr<REditorWindowViewModel> WindowViewModel)
{
    Windows.Add(WindowViewModel);
    OnWindowRegistered.Broadcast(WindowViewModel);
}

void REditorWindowGroupViewModel::UnregisterWindow(TSharedObjectPtr<REditorWindowViewModel> WindowViewModel)
{
    Windows.Remove(WindowViewModel);
    OnWindowUnregistered.Broadcast(WindowViewModel);
}

TVector<TSharedObjectPtr<REditorWindowViewModel>> REditorWindowGroupViewModel::GetWindows() const
{
    return Windows;
}

void REditorWindowGroupViewModel::CloseWindow(TSharedObjectPtr<REditorWindowViewModel> WindowViewModel)
{
    REditorWindowGroupModel::Get()->CloseWindow(WindowViewModel->GetModel());
}

TSharedObjectPtr<REditorPageViewModel> REditorWindowGroupViewModel::GetActivedPageViewModel() const
{
    if(!REditorWindowGroupModel::Get()->GetFocusedPage())
    {
        return nullptr;
    }
    return REditorWindowGroupModel::Get()->GetFocusedPage()->ViewModel;
}

bool REditorWindowGroupViewModel::CutInActivedPage() 
{
    auto Page = GetActivedPageViewModel();
    if(!Page)
    {
        return false;
    }
    return Page->Cut();
}

bool REditorWindowGroupViewModel::CopyInActivedPage() 
{
    auto Page = GetActivedPageViewModel();
    if(!Page)
    {
        return false;
    }
    return Page->Copy();
}

bool REditorWindowGroupViewModel::PasteInActivedPage() 
{
    auto Page = GetActivedPageViewModel();
    if(!Page)
    {
        return false;
    }
    return Page->Paste();
}

bool REditorWindowGroupViewModel::OpenFindTextDialogInActivedPage()
{
    REditorWindowGroupModel::Get()->GetFocusedPageArea()->OpenSearchTextDialog();
    return true;
}

bool REditorWindowGroupViewModel::OpenReplaceTextDialogInActivedPage()
{
    REditorWindowGroupModel::Get()->GetFocusedPageArea()->OpenReplaceTextDialog();
    return true;
}

bool REditorWindowGroupViewModel::SaveActivedPage()
{
    auto Page = GetActivedPageViewModel();
    if(!Page)
    {
        return false;
    }
    Page->SaveFile();

    return true;
}

bool REditorWindowGroupViewModel::UndoActivedPage()
{
    auto Page = GetActivedPageViewModel();
    if(!Page)
    {
        return false;
    }
    return Page->Undo();
}

bool REditorWindowGroupViewModel::CanUndoActivedPage()
{
    auto Page = GetActivedPageViewModel();
    if(!Page)
    {
        return false;
    }
    return Page->CanUndo();
}

bool REditorWindowGroupViewModel::RedoActivedPage()
{
    auto Page = GetActivedPageViewModel();
    if(!Page)
    {
        return false;
    }
    return Page->Redo();
}

bool REditorWindowGroupViewModel::CanRedoActivedPage()
{
    auto Page = GetActivedPageViewModel();
    if(!Page)
    {
        return false;
    }
    return Page->CanRedo();
}

TSharedObjectPtr<REditorWindowViewModel> REditorWindowGroupViewModel::CreateWindowViewModel(TSharedObjectPtr<REditorWindowModel> WindowModel)
{
    auto ViewModel = NewObject<REditorWindowViewModel>(
        REditor::Get()->GetViewModelClass(WindowModel->GetClass())
        ,this);
    ViewModel->BindModel(WindowModel);
    return ViewModel;
  
}

void REditorWindowGroupViewModel::ShowToolyipLater(
    const TWidgetAttribute<CString>& InTooltipContent
    ,TSharedObjectPtr<RWidget> InAroundWidget)
{
    Tooltip->Show(InTooltipContent, InAroundWidget);
}

void REditorWindowGroupViewModel::HideTooltip()
{
    Tooltip->Hide();
}

void REditorWindowGroupViewModel::ShowContextMenu(
    const TVector<SEditorContextMenuLine> &InRootItems
    , const SIntPoint &InScreenPosition
    , float InRootMenuWidth
    , TDelegate<void> InOnContextMenuClosed
    )
{
    ContextMenu->SetRootItem(
        InRootItems
        , InScreenPosition
        , InRootMenuWidth
        , InOnContextMenuClosed
        );
}

void REditorWindowGroupViewModel::ShowContextMenu(const TVector<SEditorContextMenuLine> &InRootItems, TSharedObjectPtr<RWidget> InAroundWidget, float InRootMenuWidth)
{
    ContextMenu->SetRootItem(InRootItems, InAroundWidget, InRootMenuWidth);
}

void REditorWindowGroupViewModel::HideContextMenu()
{
    ContextMenu->Clear();
}

bool REditorWindowGroupViewModel::IsContextMenuVisible() const
{
    return !ContextMenu->IsEmpty();
}
